
/*
 * Copyright (c) 2023 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "./napi_arkui.h"
#include "../ui/component/arkui_text.h"
#include "../ui/container/arkui_column.h"
#include "../ui/container/arkui_row.h"
#include "../ui/node/node_manager.h"
#include "model/ui/component/arkui_canvas.h"
#include "native_drawing/drawing_brush.h"
#include "native_drawing/drawing_canvas.h"
#include "native_drawing/drawing_path.h"
#include "native_drawing/drawing_point.h"
#include "native_drawing/drawing_shader_effect.h"
#include "native_drawing/drawing_text_blob.h"
#include "native_drawing/drawing_text_typography.h"
#include "hilog/log.h"

namespace NativeArkuiNapi {
std::shared_ptr<NativeArkUI::NativeColumn> CreateColumn() {
    auto columnNode = std::make_shared<NativeArkUI::NativeColumn>();
    columnNode->SetWidth(1.f, true);
    columnNode->SetHeight(1.f, true);
    columnNode->SetBackgroundColor(0x00000000);
//    columnNode->SetMargin(100, 100, 0, 0);
    return columnNode;
}

std::shared_ptr<NativeArkUI::NativeRow> CreateTextColorGradient() {
    auto rowNode = std::make_shared<NativeArkUI::NativeRow>();
    rowNode->SetLinearGradient(ARKUI_LINEAR_GRADIENT_DIRECTION_RIGHT, {0xFFF563FF, 0xFF0253EB, 0xFF0253EB, 0xFF26ECFF},
                               {0.0, 0.2, 0.5, 0.9});
    rowNode->SetBlendMode(ARKUI_BLEND_MODE_SRC_OVER, BLEND_APPLY_TYPE_OFFSCREEN);
    auto textNode = std::make_shared<NativeArkUI::NativeText>();
    textNode->SetText("路线亮点");
    textNode->SetFontSize(50);
    textNode->SetFontWeight(ARKUI_FONT_WEIGHT_BOLD);
    textNode->SetBlendMode(ARKUI_BLEND_MODE_DST_IN, BLEND_APPLY_TYPE_OFFSCREEN);
    rowNode->AddChild(textNode);
    return rowNode;
}

std::shared_ptr<NativeArkUI::NativeCanvas> CreateCanvas() {
    auto canvasNode = std::make_shared<NativeArkUI::NativeCanvas>();
    canvasNode->SetWidth(200);
    canvasNode->SetHeight(200);
    std::function<void(ArkUI_DrawContext *)> canvasDrawCallback = [](ArkUI_DrawContext *drawContext) {
        // 获取图形绘制对象。
        auto drawCanvas = reinterpret_cast<OH_Drawing_Canvas *>(OH_ArkUI_DrawContext_GetCanvas(drawContext));
        // 开始点
        OH_Drawing_Point *startPt = OH_Drawing_PointCreate(100, 100);
        // 结束点
        OH_Drawing_Point *endPt = OH_Drawing_PointCreate(900, 900);
        // 颜色数组
        uint32_t colors[] = {0xFFF563FF, 0xFF0253EB, 0xFF0253EB, 0xFF26ECFF};
        // 相对位置数组
        float pos[] = {0.0f, 0.2f, 0.5f, 0.9};
        // 创建线性渐变着色器效果
        OH_Drawing_ShaderEffect *colorShaderEffect =
            OH_Drawing_ShaderEffectCreateLinearGradient(startPt, endPt, colors, pos, 4, OH_Drawing_TileMode::CLAMP);
        // 创建画刷对象
        OH_Drawing_Brush *brush = OH_Drawing_BrushCreate();
        // 基于画刷设置着色器效果
        OH_Drawing_BrushSetShaderEffect(brush, colorShaderEffect);
        // 设置画刷填充效果
        OH_Drawing_CanvasAttachBrush(drawCanvas, brush);
        // 创建字型对象
        OH_Drawing_Font *font = OH_Drawing_FontCreate();
        // 设置字体大小
        OH_Drawing_FontSetTextSize(font, 150);
        const char *str = "路线亮点";
        // 创建字块对象
        OH_Drawing_TextBlob *textBlob =
            OH_Drawing_TextBlobCreateFromString(str, font, OH_Drawing_TextEncoding::TEXT_ENCODING_UTF8);
        // 绘制字块
        OH_Drawing_CanvasDrawTextBlob(drawCanvas, textBlob, 0, 200);
        // 取消填充效果
        OH_Drawing_CanvasDetachBrush(drawCanvas);
        // 销毁各类对象
        OH_Drawing_TextBlobDestroy(textBlob);
        OH_Drawing_FontDestroy(font);
        OH_Drawing_BrushDestroy(brush);
    };
    canvasNode->SetOnDrawCallback(canvasDrawCallback);
    return canvasNode;
}

napi_value CreateNativeRoot(napi_env env, napi_callback_info info) {
    size_t argc = 1;
    napi_value args[1] = {nullptr};
    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
    // 获取NodeContent
    ArkUI_NodeContentHandle contentHandle;
    OH_ArkUI_GetNodeContentFromNapiValue(env, args[0], &contentHandle);
    NativeArkUI::NodeManager::SetContentHandle(contentHandle);

    auto column = CreateColumn();
    auto child = CreateTextColorGradient();
    column->AddChild(child);
        auto canvasChild = CreateCanvas();

        column->AddChild(canvasChild);
    NativeArkUI::NodeManager::SetRootNode(column);
    return nullptr;
}

napi_value DestroyNativeRoot(napi_env env, napi_callback_info info) {
    // 从管理类中释放Native侧对象。
    NativeArkUI::NodeManager::DisposeRootNode();
    return nullptr;
}

void ArkuiManager::Export(napi_env env, napi_value exports) {
    if ((env == nullptr) || (exports == nullptr)) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_DOMAIN, "NativeArkuiNapi", "Export: env or exports is null");
        return;
    }

    napi_property_descriptor desc[] = {
        {"createNativeRoot", nullptr, CreateNativeRoot, nullptr, nullptr, nullptr, napi_default, nullptr},
        {"destroyNativeRoot", nullptr, DestroyNativeRoot, nullptr, nullptr, nullptr, napi_default, nullptr}};
    if (napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc) != napi_ok) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_DOMAIN, "NativeArkuiNapi", "Export: napi_define_properties failed");
    }
}

} // namespace NativeArkuiNapi